/**
 * 字典数据获取器
 * 统一处理各模块字典数据的获取、缓存和管理
 * 
 * 功能特性：
 * - 支持多模块字典数据获取（系统、BOM、产品、库存、AI）
 * - 智能缓存机制，提高数据访问性能
 * - 自动过期清理，避免内存泄漏
 * - 类型安全，提供完整的TypeScript类型定义
 * - 统一的数据转换接口，支持枚举、标签和选项格式
 * 
 * 主要函数：
 * - getDictType: 获取字典类型信息
 * - getDictData: 获取系统字典数据列表
 * - getBOMDictDataByType: 获取BOM模块字典数据
 * - generateEnumFromDict: 从字典数据生成枚举对象
 * - getDictLabel: 获取字典值对应的标签
 * - initDictData: 批量初始化字典数据到缓存
 * - clearDictCache: 清除字典缓存
 * - clearExpiredCache: 清除过期的缓存项
 * - getCacheStats: 获取缓存统计信息
 */
import type { SystemDictDataApi, SystemDictTypeApi } from '#/api/system';
import { getDictDataList, getDictTypeList } from '#/api/system';
import { getBOMDictData } from '#/api/bom/bom';
import { isBOMDictType, isProductDictType, isInventoryDictType, isAIDictType } from './types';

// 缓存配置
const CACHE_EXPIRY_TIME = 30 * 60 * 1000; // 30分钟缓存过期时间

// 缓存项接口
interface CacheItem<T> {
  data: T;
  timestamp: number;
}

// 字典数据缓存
const dictCache = new Map<string, CacheItem<SystemDictDataApi.SystemDictData[]>>();
const dictTypeCache = new Map<string, CacheItem<SystemDictTypeApi.SystemDictType>>();
const bomDictCache = new Map<string, CacheItem<Record<string, any>>>(); // BOM字典数据缓存

/**
 * 检查缓存是否过期
 * @param cacheItem 缓存项
 * @returns 是否过期
 * 
 * @example
 * ```typescript
 * const cacheItem: CacheItem<MyData> = {
 *   data: { id: 1, name: '测试' },
 *   timestamp: Date.now() - 60 * 60 * 1000 // 1小时前
 * };
 * 
 * if (isCacheExpired(cacheItem)) {
 *   console.log('缓存已过期');
 * } else {
 *   console.log('缓存仍然有效');
 * }
 * ```
 */
function isCacheExpired<T>(cacheItem: CacheItem<T>): boolean {
  return Date.now() - cacheItem.timestamp > CACHE_EXPIRY_TIME;
}

/**
 * 获取有效的缓存数据，如果过期则返回null
 * @param cache 缓存Map
 * @param key 缓存键
 * @returns 有效的缓存数据或null
 * 
 * @example
 * ```typescript
 * const cache = new Map<string, CacheItem<User[]>>();
 * cache.set('users', {
 *   data: [{ id: 1, name: '张三' }],
 *   timestamp: Date.now()
 * });
 * 
 * const users = getValidCacheData(cache, 'users');
 * if (users) {
 *   console.log('从缓存获取用户数据:', users);
 * } else {
 *   console.log('缓存无效或不存在');
 * }
 * ```
 */
function getValidCacheData<T>(cache: Map<string, CacheItem<T>>, key: string): T | null {
  const cacheItem = cache.get(key);
  if (cacheItem && !isCacheExpired(cacheItem)) {
    return cacheItem.data;
  }
  return null;
}

/**
 * 设置缓存数据
 * @param cache 缓存Map
 * @param key 缓存键
 * @param data 缓存数据
 * 
 * @example
 * ```typescript
 * const cache = new Map<string, CacheItem<Product[]>>();
 * const products = [
 *   { id: 1, name: '产品A', price: 100 },
 *   { id: 2, name: '产品B', price: 200 }
 * ];
 * 
 * // 将产品数据存入缓存
 * setCacheData(cache, 'products', products);
 * 
 * // 验证数据已缓存
 * const cachedProducts = getValidCacheData(cache, 'products');
 * console.log('缓存的产品数据:', cachedProducts);
 * ```
 */
function setCacheData<T>(cache: Map<string, CacheItem<T>>, key: string, data: T): void {
  cache.set(key, {
    data,
    timestamp: Date.now()
  });
}

/**
 * 获取字典类型数据
 * @param dictTypeValue 字典类型值
 * @param useCache 是否使用缓存，默认为true
 * @returns 字典类型对象
 * 
 * @example
 * ```typescript
 * // 获取用户状态字典类型
 * const userStatusType = await getDictType('user_status');
 * if (userStatusType) {
 *   console.log('字典类型名称:', userStatusType.name);
 *   console.log('字典类型描述:', userStatusType.description);
 * } else {
 *   console.log('未找到指定的字典类型');
 * }
 * 
 * // 不使用缓存获取最新数据
 * const freshDictType = await getDictType('user_status', false);
 * ```
 */
export async function getDictType(dictTypeValue: string, useCache: boolean = true): Promise<SystemDictTypeApi.SystemDictType | null> {
  // 尝试从缓存获取
  if (useCache) {
    const cachedData = getValidCacheData(dictTypeCache, dictTypeValue);
    if (cachedData) {
      return cachedData;
    }
  }

  try {
    const dictTypes = await getDictTypeList({ value: dictTypeValue });
    if (dictTypes.length > 0) {
      // 缓存数据
      if (useCache) {
        setCacheData(dictTypeCache, dictTypeValue, dictTypes[0]);
      }
      return dictTypes[0];
    }
    return null;
  } catch (error) {
    console.error(`获取字典类型失败: ${dictTypeValue}`, error);
    return null;
  }
}

/**
 * 获取字典数据列表
 * @param dictTypeValue 字典类型值
 * @param useCache 是否使用缓存，默认为true
 * @returns 字典数据列表
 * 
 * @example
 * ```typescript
 * // 获取用户状态字典数据
 * const userStatusData = await getDictData('user_status');
 * if (userStatusData.length > 0) {
 *   console.log('用户状态选项:');
 *   userStatusData.forEach(item => {
 *     console.log(`值: ${item.value}, 标签: ${item.label}`);
 *   });
 * } else {
 *   console.log('未找到字典数据');
 * }
 * 
 * // 在组件中使用
 * const statusOptions = await getDictData('user_status');
 * // statusOptions 可用于下拉选择框的数据源
 * ```
 */
export async function getDictData(dictTypeValue: string, useCache: boolean = true): Promise<SystemDictDataApi.SystemDictData[]> {
  // 尝试从缓存获取
  if (useCache) {
    const cachedData = getValidCacheData(dictCache, dictTypeValue);
    if (cachedData) {
      return cachedData;
    }
  }

  try {
    const dictType = await getDictType(dictTypeValue, useCache);
    if (!dictType) {
      return [];
    }

    const dictDataList = await getDictDataList({ dict_type: dictType.id });
    
    // 缓存数据
    if (useCache) {
      setCacheData(dictCache, dictTypeValue, dictDataList);
    }
    
    return dictDataList;
  } catch (error) {
    console.error(`获取字典数据失败: ${dictTypeValue}`, error);
    return [];
  }
}

/**
 * 获取BOM模块字典数据
 * @param dictTypeValue 字典类型值
 * @param useCache 是否使用缓存，默认为true
 * @returns 字典数据对象
 * 
 * @example
 * ```typescript
 * // 获取BOM类型字典数据
 * const bomTypeData = await getBOMDictDataByType('bom_type');
 * if (Object.keys(bomTypeData).length > 0) {
 *   console.log('BOM类型选项:');
 *   Object.entries(bomTypeData).forEach(([value, label]) => {
 *     console.log(`值: ${value}, 标签: ${label}`);
 *   });
 * } else {
 *   console.log('未找到BOM字典数据');
 * }
 * 
 * // 在组件中使用
 * const bomOptions = await getBOMDictDataByType('bom_type');
 * // 将对象转换为选项数组用于下拉选择
 * const optionsArray = Object.entries(bomOptions).map(([value, label]) => ({
 *   value,
 *   label
 * }));
 * ```
 */
export async function getBOMDictDataByType(dictTypeValue: string, useCache: boolean = true): Promise<Record<string, any>> {
  // 尝试从缓存获取
  if (useCache) {
    const cachedData = getValidCacheData(bomDictCache, dictTypeValue);
    if (cachedData) {
      return cachedData;
    }
  }

  try {
    const response = await getBOMDictData(dictTypeValue);
    if (response.data) {
      // 缓存数据
      if (useCache) {
        setCacheData(bomDictCache, dictTypeValue, response.data);
      }
      return response.data;
    }
    return {};
  } catch (error) {
    console.error(`获取BOM字典数据失败: ${dictTypeValue}`, error);
    return {};
  }
}

/**
 * 获取所有BOM模块字典数据
 * @param useCache 是否使用缓存，默认为true
 * @returns 所有BOM字典数据对象
 * 
 * @example
 * ```typescript
 * // 获取所有BOM字典数据
 * const allBomDictData = await getAllBOMDictData();
 * if (Object.keys(allBomDictData).length > 0) {
 *   console.log('BOM字典类型列表:');
 *   Object.keys(allBomDictData).forEach(dictType => {
 *     console.log(`字典类型: ${dictType}`);
 *   });
 *   
 *   // 访问特定字典类型的数据
 *   if (allBomDictData['bom_type']) {
 *     console.log('BOM类型数据:', allBomDictData['bom_type']);
 *   }
 * } else {
 *   console.log('未找到任何BOM字典数据');
 * }
 * 
 * // 在应用初始化时预加载所有BOM字典
 * await getAllBOMDictData();
 * // 后续调用特定字典类型时将使用缓存
 * const bomTypeData = await getBOMDictDataByType('bom_type');
 * ```
 */
export async function getAllBOMDictData(useCache: boolean = true): Promise<Record<string, Record<string, any>>> {
  try {
    const response = await getBOMDictData();
    if (response.data) {
      // 缓存所有字典数据
      Object.keys(response.data).forEach(dictType => {
        if (useCache) {
          setCacheData(bomDictCache, dictType, response.data[dictType]);
        }
      });
      return response.data;
    }
    return {};
  } catch (error) {
    console.error('获取所有BOM字典数据失败', error);
    return {};
  }
}

/**
 * 字典模块类型
 */
export type DictModuleType = 'bom' | 'system' | 'product' | 'inventory' | 'ai';

/**
 * 字典选项接口
 */
export interface DictOption {
  label: string;
  value: string;
  colorType?: string;
  cssClass?: string;
}

/**
 * 字典枚举结果接口
 */
export interface DictEnumResult {
  enum: Record<string, string>;
  labels: Record<string, string>;
  options: Array<DictOption>;
}

/**
 * 从字典数据生成枚举对象
 * @param dictTypeValue 字典类型值
 * @param module 模块名称，可选，用于指定字典所属模块
 * @param useCache 是否使用缓存，默认为true
 * @returns 枚举对象，包含键值对和标签映射
 * 
 * @example
 * ```typescript
 * // 获取系统字典枚举
 * const statusEnum = await generateEnumFromDict('user_status');
 * console.log('枚举对象:', statusEnum.enum); // { '1': '1', '2': '2', '0': '0' }
 * console.log('标签映射:', statusEnum.labels); // { '1': '启用', '2': '禁用', '0': '锁定' }
 * console.log('选项数组:', statusEnum.options); // [{ label: '启用', value: '1' }, ...]
 * 
 * // 指定模块获取字典枚举
 * const bomTypeEnum = await generateEnumFromDict('bom_type', 'bom');
 * 
 * // 在表单中使用
 * const { enum: statusEnum, options: statusOptions } = await generateEnumFromDict('user_status');
 * 
 * // 在Vue组件中使用
 * // const formSchema = {
 * //   type: 'select',
 * //   options: statusOptions,
 * //   enum: statusEnum
 * // };
 * ```
 */
export async function generateEnumFromDict(
  dictTypeValue: string, 
  module?: DictModuleType, 
  useCache: boolean = true
): Promise<DictEnumResult> {
  // 根据模块或字典类型自动判断字典类型
  let dictModuleType: DictModuleType = 'system';
  
  if (module) {
    // 如果指定了模块，使用指定的模块类型
    dictModuleType = module;
  } else {
    // 如果未指定模块，根据字典类型判断
    if (isBOMDictType(dictTypeValue)) {
      dictModuleType = 'bom';
    } else if (isProductDictType(dictTypeValue)) {
      dictModuleType = 'product';
    } else if (isInventoryDictType(dictTypeValue)) {
      dictModuleType = 'inventory';
    } else if (isAIDictType(dictTypeValue)) {
      dictModuleType = 'ai';
    } else {
      dictModuleType = 'system';
    }
  }
  
  // 根据模块类型获取字典数据
  let dictDataObj: Record<string, any> = {};
  let dictDataList: SystemDictDataApi.SystemDictData[] = [];
  
  if (dictModuleType === 'bom') {
    // 从BOM字典获取数据
    dictDataObj = await getBOMDictDataByType(dictTypeValue, useCache);
  } else {
    // 从系统字典获取数据
    dictDataList = await getDictData(dictTypeValue, useCache);
  }
  
  const enumObj: Record<string, string> = {};
  const labels: Record<string, string> = {};
  const options: Array<DictOption> = [];

  if (dictModuleType === 'bom') {
    // 处理BOM字典数据
    Object.keys(dictDataObj).forEach(value => {
      const label = dictDataObj[value];
      enumObj[value] = value;
      labels[value] = label;
      options.push({
        label,
        value,
      });
    });
  } else {
    // 处理系统字典数据
    dictDataList.forEach(item => {
      // 将value作为键，label作为值
      enumObj[item.value] = item.value;
      // 创建标签映射
      labels[item.value] = item.label;
      // 创建选项数组，用于下拉选择等组件
      options.push({
        label: item.label,
        value: item.value,
        colorType: item.color_type,
        cssClass: item.css_class,
      });
    });
  }

  return {
    enum: enumObj,
    labels,
    options,
  };
}

/**
 * 获取字典标签
 * @param dictTypeValue 字典类型值
 * @param value 字典值
 * @param module 模块名称，可选，用于指定字典所属模块
 * @param useCache 是否使用缓存，默认为true
 * @returns 字典标签
 * 
 * @example
 * ```typescript
 * // 获取用户状态标签
 * const statusLabel = await getDictLabel('user_status', '1');
 * console.log('状态标签:', statusLabel); // 输出: "启用"
 * 
 * // 获取BOM字典标签
 * const bomTypeLabel = await getDictLabel('bom_type', '1', 'bom');
 * console.log('BOM类型标签:', bomTypeLabel);
 * 
 * // 在表格列中使用
 * // const columns = [
 * //   {
 * //     title: '状态',
 * //     dataIndex: 'status',
 * //     customRender: ({ text }) => {
 * //       return getDictLabel('user_status', text);
 * //     }
 * //   }
 * // ];
 * 
 * // 在表单验证消息中使用
 * // const validator = async (rule, value) => {
 * //   if (!value) {
 * //     const label = await getDictLabel('user_status', rule.field);
 * //     return Promise.reject(`请选择${label}`);
 * //   }
 * //   return Promise.resolve();
 * // };
 * ```
 */
export async function getDictLabel(
  dictTypeValue: string, 
  value: string, 
  module?: DictModuleType,
  useCache: boolean = true
): Promise<string> {
  // 根据模块或字典类型自动判断字典类型
  let dictModuleType: DictModuleType = 'system';
  
  if (module) {
    // 如果指定了模块，使用指定的模块类型
    dictModuleType = module;
  } else {
    // 如果未指定模块，根据字典类型判断
    if (isBOMDictType(dictTypeValue)) {
      dictModuleType = 'bom';
    } else if (isProductDictType(dictTypeValue)) {
      dictModuleType = 'product';
    } else if (isInventoryDictType(dictTypeValue)) {
      dictModuleType = 'inventory';
    } else if (isAIDictType(dictTypeValue)) {
      dictModuleType = 'ai';
    } else {
      dictModuleType = 'system';
    }
  }
  
  if (dictModuleType === 'bom') {
    // 从BOM字典获取数据
    const dictDataObj = await getBOMDictDataByType(dictTypeValue, useCache);
    return dictDataObj[value] || value;
  } else {
    // 从系统字典获取数据
    const dictData = await getDictData(dictTypeValue, useCache);
    const item = dictData.find(item => item.value === value);
    return item ? item.label : value;
  }
}

/**
 * 清除字典缓存
 * @param dictTypeValue 字典类型值，可选，如果不提供则清除所有缓存
 * 
 * @example
 * ```typescript
 * // 清除特定字典类型的缓存
 * clearDictCache('user_status');
 * console.log('已清除用户状态字典缓存');
 * 
 * // 清除所有字典缓存
 * clearDictCache();
 * console.log('已清除所有字典缓存');
 * 
 * // 在字典数据更新后清除缓存
 * // await updateDictData('user_status', newStatusData);
 * // clearDictCache('user_status'); // 确保下次获取最新数据
 * 
 * // 在用户登出时清除所有缓存
 * // function handleLogout() {
 * //   clearDictCache();
 * //   // 其他登出逻辑...
 * // }
 * ```
 */
export function clearDictCache(dictTypeValue?: string): void {
  if (dictTypeValue) {
    dictCache.delete(dictTypeValue);
    dictTypeCache.delete(dictTypeValue);
    bomDictCache.delete(dictTypeValue);
  } else {
    dictCache.clear();
    dictTypeCache.clear();
    bomDictCache.clear();
  }
}

/**
 * 清除过期的缓存项
 * 
 * @example
 * ```typescript
 * // 定期清理过期缓存
 * setInterval(() => {
 *   clearExpiredCache();
 *   console.log('已清理过期缓存');
 * }, 60 * 60 * 1000); // 每小时清理一次
 * 
 * // 在应用空闲时清理过期缓存
 * document.addEventListener('visibilitychange', () => {
 *   if (!document.hidden) {
 *     clearExpiredCache();
 *   }
 * });
 * 
 * // 获取清理前的缓存统计
 * const beforeStats = getCacheStats();
 * clearExpiredCache();
 * const afterStats = getCacheStats();
 * console.log(`清理前缓存项: ${JSON.stringify(beforeStats)}`);
 * console.log(`清理后缓存项: ${JSON.stringify(afterStats)}`);
 * ```
 */
export function clearExpiredCache(): void {
  // 清除过期的字典数据缓存
  for (const [key, cacheItem] of dictCache.entries()) {
    if (isCacheExpired(cacheItem)) {
      dictCache.delete(key);
    }
  }
  
  // 清除过期的字典类型缓存
  for (const [key, cacheItem] of dictTypeCache.entries()) {
    if (isCacheExpired(cacheItem)) {
      dictTypeCache.delete(key);
    }
  }
  
  // 清除过期的BOM字典缓存
  for (const [key, cacheItem] of bomDictCache.entries()) {
    if (isCacheExpired(cacheItem)) {
      bomDictCache.delete(key);
    }
  }
}

/**
 * 获取缓存统计信息
 * @returns 缓存统计对象
 * 
 * @example
 * ```typescript
 * // 获取当前缓存统计
 * const stats = getCacheStats();
 * console.log(`字典数据缓存项数: ${stats.dictCache}`);
 * console.log(`字典类型缓存项数: ${stats.dictTypeCache}`);
 * console.log(`BOM字典缓存项数: ${stats.bomDictCache}`);
 * 
 * // 监控缓存使用情况
 * function logCacheStats() {
 *   const stats = getCacheStats();
 *   const total = stats.dictCache + stats.dictTypeCache + stats.bomDictCache;
 *   console.log(`缓存使用情况 - 总计: ${total}, 字典数据: ${stats.dictCache}, 字典类型: ${stats.dictTypeCache}, BOM字典: ${stats.bomDictCache}`);
 * }
 * 
 * // 在开发环境中定期输出缓存统计
 * if (process.env.NODE_ENV === 'development') {
 *   setInterval(logCacheStats, 5 * 60 * 1000); // 每5分钟输出一次
 * }
 * 
 * // 在内存使用过高时清理缓存
 * const stats = getCacheStats();
 * const totalCacheItems = stats.dictCache + stats.dictTypeCache + stats.bomDictCache;
 * if (totalCacheItems > 100) {
 *   console.warn('缓存项过多，执行清理');
 *   clearExpiredCache();
 * }
 * ```
 */
export function getCacheStats(): {
  dictCache: number;
  dictTypeCache: number;
  bomDictCache: number;
} {
  return {
    dictCache: dictCache.size,
    dictTypeCache: dictTypeCache.size,
    bomDictCache: bomDictCache.size,
  };
}

/**
 * 初始化字典数据
 * @param dictTypes 字典类型数组
 * @param useCache 是否使用缓存，默认为true
 * 
 * @example
 * ```typescript
 * // 应用启动时预加载常用字典
 * const commonDictTypes = [
 *   'user_status',
 *   'user_type',
 *   'bom_type',
 *   'material_type'
 * ];
 * 
 * // 在应用初始化时预加载字典数据
 * async function initializeApp() {
 *   try {
 *     await initDictData(commonDictTypes);
 *     console.log('字典数据预加载完成');
 *   } catch (error) {
 *     console.error('字典数据预加载失败:', error);
 *   }
 *   // 其他初始化逻辑...
 * }
 * 
 * // 在路由守卫中加载字典数据
 * router.beforeEach(async (to, from, next) => {
 *   if (to.meta.requiresDict) {
 *     const dictTypes = to.meta.dictTypes as string[];
 *     await initDictData(dictTypes);
 *   }
 *   next();
 * });
 * 
 * // 在组件中使用
 * // onMounted(async () => {
 * //   await initDictData(['user_status', 'user_type']);
 * //   // 字典数据已加载到缓存中，后续调用将使用缓存
 * // });
 * ```
 */
export async function initDictData(dictTypes: string[], useCache: boolean = true): Promise<void> {
  const promises = dictTypes.map(async dictType => {
    if (isBOMDictType(dictType)) {
      return getBOMDictDataByType(dictType, useCache);
    } else {
      return getDictData(dictType, useCache);
    }
  });
  
  await Promise.all(promises);
}